Skip to content

feat: datacube shared-state for AnalysisInterferometer via curvature preloads - #566

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/datacube-shared-state
Jun 8, 2026
Merged

Jammy2211 merged 2 commits into
mainfrom
feature/datacube-shared-state

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

Implements the lensing consumer of the FactorGraphModel cross-Analysis shared-state mechanism (PyAutoFit, shipped) for the interferometer datacube (PyAutoLens#565 / the analysis_shared_state epic). When a datacube is fit as N AnalysisInterferometer channels sharing one lens model, the curvature matrix F = LᵀW̃L — the dominant per-channel inversion-setup cost — is identical for every channel. This builds it once on the lead factor and reuses it across every channel via the PyAutoArray Preloads API, targeting a large reduction in the inversion-setup cost for a many-channel cube.

This is the curvature-sharing increment (the dominant ~86% of the shareable inversion-setup work). Mapper-sharing (the Delaunay rebuild) and the workspace scripts / profiling re-measure follow.

Depends on Jammy2211/PyAutoArray (Preloads API) — that PR must merge first.

API Changes

All additive and backward compatible — no removals or renames.

  • AnalysisInterferometer.__init__ gains an opt-in shared_preloads=False flag.
  • New method AnalysisInterferometer.shared_state_from(instance) — returns a PreloadsInterferometer with the channel-invariant curvature_matrix (or None when not opted in / no inversion).
  • AnalysisInterferometer.log_likelihood_function gains shared=None; fit_from gains preloads=None; FitInterferometer and TracerToInversion gain preloads=None, threaded into inversion_from.

See full details below.

Test Plan

  • python -m pytest test_autolens/ — full suite passes (331 tests)
  • New test_autolens/interferometer/model/test_analysis_interferometer.py: shared_state_from yields a PreloadsInterferometer whose curvature_matrix is reused by the fit (identity) with unchanged figure_of_merit; log_likelihood_function(shared=...) matches the unshared call; returns None when not opted in.
  • JAX (verified locally; committed test lands in autolens_workspace_test): PreloadsInterferometer threads through jax.jit and the shared-path likelihood matches numpy.
Full API Changes (for automation & release notes)

Added

  • AnalysisInterferometer.shared_state_from(self, instance) — builds the shared PreloadsInterferometer once per evaluation (the autofit.Analysis.shared_state_from hook for interferometer datacubes).

Changed Signature (backward compatible — new optional args / flags)

  • AnalysisInterferometer.__init__(... , shared_preloads=False)
  • AnalysisInterferometer.log_likelihood_function(self, instance, shared=None)
  • AnalysisInterferometer.fit_from(self, instance, preloads=None)
  • FitInterferometer.__init__(... , preloads=None)
  • TracerToInversion.__init__(... , preloads=None)

Changed Behaviour

  • When shared_preloads=True and a FactorGraphModel forwards the shared PreloadsInterferometer, each channel's inversion reuses the preloaded curvature matrix instead of rebuilding it. With the defaults, behaviour is unchanged.

Migration

  • None required. To opt in, construct the per-channel AnalysisInterferometer(..., shared_preloads=True) and combine them in a FactorGraphModel (which calls shared_state_from and forwards the result).

🤖 Generated with Claude Code

…preloads

Implement the lensing consumer of the FactorGraphModel cross-Analysis
shared-state mechanism for the interferometer datacube.

- AnalysisInterferometer gains an opt-in `shared_preloads` flag and a
  `shared_state_from(instance)` that builds the channel-invariant curvature
  matrix once and returns it in a `PreloadsInterferometer`.
- `log_likelihood_function(instance, shared=None)` and
  `fit_from(instance, preloads=None)` thread the shared object down through
  `FitInterferometer` and `TracerToInversion` into `inversion_from`, so each
  channel reuses the curvature matrix instead of rebuilding it.
- `PreloadsInterferometer` is registered as a JAX pytree so the shared object
  threads through `jax.jit` (verified: shared-path likelihood matches numpy).

Default behaviour is unchanged (`shared_preloads=False` / `shared=None`).

Depends on the PyAutoArray Preloads API (must merge first).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reuse the channel-invariant mapper across datacube channels, in addition
to the curvature matrix, so the Delaunay triangulation is built once
rather than per channel (~97% of the inversion-setup cost now shareable).

- TracerToInversion.mapper_galaxy_dict short-circuits to a preloaded mapper
  when present (linear_obj_list and linear_obj_galaxy_dict both derive from
  it, so the mapper is not rebuilt anywhere on the hot path).
- AnalysisInterferometer.shared_state_from builds one TracerToInversion and
  preloads both the curvature matrix and the mapper_galaxy_dict.
- preloads ride as no_flatten config-aux on FitInterferometer (built inside
  the jit and consumed via attribute access, never crossing a jit boundary),
  so the PreloadsInterferometer pytree registration is removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Jammy2211

Copy link
Copy Markdown
Collaborator Author

Updated (202cb6021): added mapper-sharing to the datacube shared-state path — TracerToInversion.mapper_galaxy_dict reuses a preloaded mapper (the Delaunay triangulation is no longer rebuilt per channel), and shared_state_from now preloads both the curvature matrix and the mapper. preloads ride as no_flatten config-aux on FitInterferometer (built inside the jit, consumed via attribute access, never crossing a boundary), so the PreloadsInterferometer pytree registration was removed. ~97% of the inversion-setup cost is now shareable. test_autolens 331 passing; JAX real-path (eager + jit) matches numpy.

@Jammy2211
Jammy2211 merged commit 849f58b into main Jun 8, 2026
4 of 6 checks passed
@Jammy2211
Jammy2211 deleted the feature/datacube-shared-state branch July 9, 2026 09:33
@Jammy2211 Jammy2211 removed the pending-release PR queued for the next release build label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant